package com.matrix.framework.core.upload;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.http.codec.multipart.DefaultPartHttpMessageReader;
import org.springframework.http.codec.multipart.MultipartHttpMessageReader;
import org.springframework.util.unit.DataSize;
import org.springframework.web.reactive.config.WebFluxConfigurer;

/**
 * 文件上传配置类
 *
 * Copyright © 海平面工作室 版权所有
 *
 * @Author: Leo
 * @Create: 2025-08-17 10:00:00
 * @Since 1.2
 */
@Configuration
@ConfigurationProperties(prefix = "matrix.upload")
public class FileUploadConfig implements WebFluxConfigurer {
    
    // 最大文件大小（默认2GB）
    private DataSize maxFileSize = DataSize.ofGigabytes(2);
    
    // 最大请求大小（默认10GB）
    private DataSize maxRequestSize = DataSize.ofGigabytes(10);
    
    // 内存中缓冲区大小（默认4MB）
    private DataSize maxInMemorySize = DataSize.ofMegabytes(4);
    
    /**
     * 配置WebFlux的编解码器，用于大文件上传的适当设置
     * 
     * @param configurer 服务器编解码器配置器
     */
    @Override
    public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
        DefaultPartHttpMessageReader partReader = new DefaultPartHttpMessageReader();
        // 设置最大内存缓冲区大小
        partReader.setMaxInMemorySize((int) maxInMemorySize.toBytes());
        // 设置最大磁盘使用量
        partReader.setMaxDiskUsagePerPart(maxFileSize.toBytes());
        
        MultipartHttpMessageReader multipartReader = new MultipartHttpMessageReader(partReader);
        configurer.defaultCodecs().multipartReader(multipartReader);
        
        // 设置最大请求体大小
        configurer.defaultCodecs().maxInMemorySize((int) (maxRequestSize.toBytes() / 1024 / 1024));
    }
    
    public DataSize getMaxFileSize() {
        return maxFileSize;
    }
    
    public void setMaxFileSize(DataSize maxFileSize) {
        this.maxFileSize = maxFileSize;
    }
    
    public DataSize getMaxRequestSize() {
        return maxRequestSize;
    }
    
    public void setMaxRequestSize(DataSize maxRequestSize) {
        this.maxRequestSize = maxRequestSize;
    }
    
    public DataSize getMaxInMemorySize() {
        return maxInMemorySize;
    }
    
    public void setMaxInMemorySize(DataSize maxInMemorySize) {
        this.maxInMemorySize = maxInMemorySize;
    }
}
